package com.zwh.se.oop.comprehensive;

/**
 * {} 标记的代码称为代码块，根据其位置的不同可以分为普通代码块、构造代码块、静态代码块。
 *
 * @author yexi
 */
public class SayAboutTheCodeBlock {

    /**
     * 静态代码块
     * 被static关键字修饰的代码块称为静态代码块。
     * 静态代码块位于类的内部、方法的外部。
     * 静态代码块只执行一次，在构造代码块、构造方法前执行。
     *
     * 当类的字节码被加载到内存时，此时程序需要加载一些资源(读取资源文件等)，可以使用静态代码块，
     *      此时被加载进来的资源一般都可以被多个实例所共享。
     */
    static {
        System.out.println("-------静态代码块------");
    }

    /**
     * 构造代码块
     * 构造代码块在类中(类的内部)、方法外
     * 构造代码块构造一个对象执行一次，在构造方法前执行。
     *
     * 如果需要在构造方法执行前加载一些资源（读取配置文件、xml文件等）时使用（简单来说就是不常用）。
     */
    {
        System.out.println("-------构造代码块------");
    }

    /**
     * 普通代码块{}，一般存在于方法中，形成作用域。
     * 作用域特性:
     * [1].作用域可以嵌套，内层作用作用域可以访问外层作用域的变量
     * [2].当访问一个变量时，首先在变量所在的作用域查找，如果能找到，停止查找并输出变量内容；当本
     * 作用域没找到时，尝试去上一次作用域查找，依次类推。这个过程形成的查找链称为作用域链。
     */
    public void aMethod() {
        System.out.println("-------普通代码块------");
    }

    public static void main(String[] args) {
        /*
            代码块执行顺序：
            最先执行静态块，只在类加载的时候执行一次，一般用于执行一些全局性的初始化操作。
            再执行构造块（不常用），
            再执行构造器，
            再执行方法中的普通块。

            静态代码块-->构造代码块（创建对象的时候才会用到）-->普通代码块
        */
        SayAboutTheCodeBlock aClass = new SayAboutTheCodeBlock();
        aClass.aMethod();
        //第二次同样道理。这次静态块就不会不执行了。
        aClass = new SayAboutTheCodeBlock();
        aClass.aMethod();
    }


}
